﻿Imports System.Runtime.CompilerServices
Imports iConverter.Extensions
Imports iConverter.Models
Imports System.Configuration
Imports System.ComponentModel
Imports iConverter.Contracts

Namespace Core


    ''' <summary>
    ''' 插件管理器
    ''' </summary>
    ''' <remarks></remarks>
    Public Module PluginsManager

        ''' <summary>
        ''' 扩展管理器对象实例
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Property Extensions As ExtensionsManager

        ''' <summary>
        ''' 插件提供器 字典
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Property DictPluginsProvider As Dictionary(Of Guid, PluginProvider)

        ''' <summary>
        ''' 后期处理插件 字典
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Property DictPostProcessing As Dictionary(Of Guid, PostProcessing)

        ''' <summary>
        ''' 处理器插件 字典
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Property DictProcesser As Dictionary(Of Guid, Processer)

        ''' <summary>
        ''' 发送到插件 字典
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Property DictSend As Dictionary(Of Guid, Send)


        ''' <summary>
        ''' 设置提供器字典
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Property DictSettingsProvider As Dictionary(Of Guid, ApplicationSettingsBase)




        ''' <summary>
        '''初始化插件管理器
        ''' </summary>
        ''' <remarks></remarks>
        Friend Sub Initialize()



            Extensions = New ExtensionsManager

            Dim provs = Extensions.Providers

            If provs Is Nothing Then
                Throw New InvalidOperationException(" Extensions  Provider is nothing.!")
            End If

            DictPluginsProvider = New Dictionary(Of Guid, PluginProvider)

            DictPostProcessing = New Dictionary(Of Guid, PostProcessing)

            DictProcesser = New Dictionary(Of Guid, Processer)

            DictSend = New Dictionary(Of Guid, Send)

            DictSettingsProvider = New Dictionary(Of Guid, ApplicationSettingsBase)

            Dim disabledproviders = SettingManager.Settings.DisabledPluginProviders

            For Each item In provs

                DictPluginsProvider.Add(item.ID, item)

                If disabledproviders.Contains(item.ID) Then
                    item.IsEnabled = False
                Else
                    InitializePluginProvider(item)

                End If
            Next

            UpdateProcessers()
        End Sub

        ''' <summary>
        ''' 初始化 Provider
        ''' </summary>
        ''' <param name="item"></param>
        ''' <remarks></remarks>
        Private Sub InitializePluginProvider(ByVal item As PluginProvider)


            Dim plugins = item.Plugins


            If plugins Is Nothing Then Return
            '为空时跳出

            If item.CanConfigure Then
                DictSettingsProvider.Add(item.ID, item.Settings)
            End If

            For Each p In plugins
                Select Case p.PluginType
                    Case PluginTypes.PostProcess
                        Dim pp = DirectCast(p, PostProcessing)

                        DictPostProcessing.Add(p.ID, pp)

                        Dim list = pp.Processings

                        For Each prc In list
                            DictProcesser.Add(prc.ID, prc)
                        Next

                    Case PluginTypes.Send
                        DictSend.Add(p.ID, p)

                    Case Else
                        '未知类型
                End Select
            Next
        End Sub

        ''' <summary>
        ''' 后期处理器已经更改
        ''' </summary>
        ''' <remarks></remarks>
        Public Event ProvidersChanged As EventHandler


        ''' <summary>
        ''' 更新后期处理器
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub UpdateProcessers()


            Dim upp = SettingManager.Settings.UsePostProcessings

            Dim hasSets As New HashSet(Of Guid)

            For Each item In upp


                If DictPluginsProvider.ContainsKey(item.ProviderID) Then
                    Dim provider = DictPluginsProvider(item.ProviderID)

                    If provider.IsEnabled AndAlso Not hasSets.Contains(item.PostProcessingID) AndAlso
                        DictPostProcessing.ContainsKey(item.PostProcessingID) AndAlso
                        DictProcesser.ContainsKey(item.SelectProcesserID) Then


                        Dim pp = DictPostProcessing(item.PostProcessingID)

                        Dim Processings = pp.Processings

                        For Each p In Processings
                            'If p.ID = item.SelectProcesserID Then
                            '    p.isSelected = True
                            'Else
                            '    p.isSelected = False
                            'End If

                            p.isSelected = (p.ID = item.SelectProcesserID)
                        Next


                        hasSets.Add(item.PostProcessingID)


                    End If
                End If
            Next


            RaiseEvent ProvidersChanged(Nothing, EventArgs.Empty)
        End Sub



        ''' <summary>
        ''' 获取插件提供器列表
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Providers As IEnumerable(Of PluginProvider)
            Get
                If DictPluginsProvider Is Nothing Then Return Enumerable.Empty(Of PluginProvider)()
                Return _DictPluginsProvider.Values
            End Get
        End Property

        ''' <summary>
        ''' 获取可用的后期处理插件
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PostProcessings As IEnumerable(Of PostProcessing)
            Get
                If DictPostProcessing Is Nothing Then Return Enumerable.Empty(Of PostProcessing)()
                'Return DictPostProcessing.Values

                '20110910 增加排序

                Dim upps = SettingManager.Settings.UsePostProcessings.Select(Function(x) (x.PostProcessingID)).ToList

                Dim getindex = Function(id As Guid)
                                   Dim i = upps.IndexOf(id)
                                   Return If(i = -1, Integer.MaxValue, i)
                               End Function


                Dim list = From item In DictPostProcessing.Values
                          Let Index = getindex(item.ID)
                          Order By Index
                          Select item



                Return list

            End Get
        End Property

        ''' <summary>
        ''' 获取所有可用的处理器
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Processers As IEnumerable(Of Processer)
            Get
                If DictProcesser Is Nothing Then Return Enumerable.Empty(Of Processer)()
                Return DictProcesser.Values
            End Get
        End Property

        ''' <summary>
        ''' 获取可用的发送到插件
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Sends As IEnumerable(Of Send)
            Get
                If DictSend Is Nothing Then Return Enumerable.Empty(Of Send)()
                Return DictSend.Values
            End Get
        End Property





        ''' <summary>
        ''' 获取插件提供器
        ''' </summary>     
        Public Function GetProvider(id As Guid) As PluginProvider
            If DictPluginsProvider IsNot Nothing AndAlso DictPluginsProvider.ContainsKey(id) Then
                Return DictPluginsProvider(id)
            End If
            Return Nothing
        End Function

        ''' <summary>
        ''' 获取后期处理插件
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetPostProcessing(id As Guid) As PostProcessing
            If DictPostProcessing IsNot Nothing AndAlso DictPostProcessing.ContainsKey(id) Then
                Return DictPostProcessing(id)
            End If
            Return Nothing
        End Function

        ''' <summary>
        ''' 获取文本处理器
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetProcesser(id As Guid) As Processer
            If DictProcesser IsNot Nothing AndAlso DictProcesser.ContainsKey(id) Then
                Return DictProcesser(id)
            End If
            Return Nothing
        End Function

        ''' <summary>
        ''' 获取发送到插件
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetSend(id As Guid) As Send
            If DictSend IsNot Nothing AndAlso DictSend.ContainsKey(id) Then Return DictSend(id)
            Return Nothing
        End Function




        ''' <summary>
        ''' 重置所有设置
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub ResetAllSettings()
            For Each item In DictSettingsProvider
                item.Value.Reset()
            Next
        End Sub

        ''' <summary>
        ''' 禁用插件
        ''' </summary>
        ''' <param name="p"></param>
        ''' <remarks></remarks>
        Public Sub DisablePlugin(p As PluginProvider)
            If p IsNot Nothing AndAlso DictPluginsProvider.ContainsKey(p.ID) Then
                Dim item = DictPluginsProvider(p.ID)


                DeinitializePluginProvider(item)

                item.IsEnabled = False
            End If
        End Sub


        ''' <summary>
        ''' 初始化 Provider
        ''' </summary>
        ''' <param name="item"></param>
        ''' <remarks></remarks>
        Private Sub DeinitializePluginProvider(ByVal item As PluginProvider)
            If item.CanConfigure Then
                DictSettingsProvider.Remove(item.ID)
            End If

            Dim plugins = item.Plugins

            For Each p In plugins
                Select Case p.PluginType
                    Case PluginTypes.PostProcess
                        Dim pp = DirectCast(p, PostProcessing)

                        DictPostProcessing.Remove(p.ID)

                        Dim list = pp.Processings

                        For Each prc In list
                            DictProcesser.Remove(prc.ID)
                        Next

                    Case PluginTypes.Send
                        DictSend.Remove(p.ID)

                    Case Else
                        '未知类型
                End Select
            Next
        End Sub


        ''' <summary>
        ''' 启用插件
        ''' </summary>
        ''' <param name="p"></param>
        ''' <remarks></remarks>
        Sub EnablePlugin(p As PluginProvider)

            If p IsNot Nothing AndAlso DictPluginsProvider.ContainsKey(p.ID) Then
                Dim item = DictPluginsProvider(p.ID)
                item.IsEnabled = True

                InitializePluginProvider(item)

                UpdateProcessers()
            End If

        End Sub



    End Module


End Namespace
